﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Threading;
using Kugar.Core.ExtMethod;
using Kugar.Core.BaseStruct;
using System.Net.Sockets;

namespace Kugar.Core.Communications.Transfer
{
    public class TransferAsyncEventArgs :EventArgs ,IDisposable
    {
        public void Clear()
        {
            Completed = null;
            Beginning = null;

            Transfer = null;
            Buffer = null;
            UserToken = null;

            BytesTransferred = 0;
            Offset = 0;
            Count = 0;
        }

        public virtual void Dispose()
        {
            Clear();
        }

        public ITransfer Transfer { get; internal protected set; }

        public byte[] Buffer { get; protected set; }

        public int Count { get; protected set; }

        public int Offset { get; protected set; }

        public int BytesTransferred { get;internal protected set; }

        public object UserToken { get; set; }

        public Exception Error { get; internal protected set; }

        public void SetBuffer(Int32 offset , Int32 count)
        {
            if (!Buffer.IsInEnableRange(offset, count))
            {
                throw new ArgumentOutOfRangeException(@"count ");
            }

            Count = count;
            Offset = offset;
        }

        public void SetBuffer(byte[] buffer, Int32 offset, Int32 count)
        {
            if (buffer==null)
            {
                throw new ArgumentNullException("buffer");
            }

            if (!buffer.IsInEnableRange(offset,count))
            {
                throw new ArgumentOutOfRangeException(@"count ");
            }

            Buffer = buffer;
            Count = count;
            Offset = offset;
        }

        public bool HasError
        {
            get { return Error != null; }
        }

        public bool IsVerified(ref Exception error)
        {
            bool retValue = true;

            if (this.Buffer==null)
            {
                error=new ArgumentNullException("error");
                retValue = false;
            }

            if (!this.Buffer.IsInEnableRange(Offset,Count))
            {
                error=new ArgumentOutOfRangeException("error");
                retValue = false;
            }

            return retValue;
        }

        public bool IsVerified()
        {
            Exception error = null;

            return IsVerified(ref error);
        }


        public event EventHandler<TransferAsyncEventArgs> Completed;

        public event EventHandler<TransferAsyncEventArgs> Beginning;

        /// <summary>
        ///     以异步的方式引发Completed事件
        /// </summary>
        /// <param name="sender"></param>
        internal protected void OnCompleted(object sender)
        {
            if (Completed!=null)
            {
                ThreadPool.QueueUserWorkItem(OnCompletedInternal, sender);
                //Completed(sender, this);
            }
        }



        internal protected void OnBeginning(object sender)
        {
            if (Beginning != null)
            {
                Beginning(sender, this);
            }
        }

        private void OnCompletedInternal(object sender)
        {
            Completed(sender, this);
        }

    }



    public class TransferAsyncEventArgsRecyclable:TransferAsyncEventArgs,IRecyclable
    {
        protected TransferAsyncEventArgsRecylePool _pool;

        public TransferAsyncEventArgsRecyclable(TransferAsyncEventArgsRecylePool parentPool)
        {
            _pool = parentPool;
        }

        #region Implementation of IRecyclable

        IRecyclablePool<IRecyclable> IRecyclable.Pool
        {
            get { return (IRecyclablePool<IRecyclable>) _pool; }
            set { }
        }

        /// <summary>
        ///     当对象真正释放的时候，回收器会调用该函数
        /// </summary>
        void IRecyclable.DisposeObject()
        {
            base.Dispose();
        }

        #endregion

        public override void Dispose()
        {
            Clear();
            _pool.RecycleObject(this);
        }
    }

    public class TransferAsyncEventArgsRecylePool : RecyclablePool<TransferAsyncEventArgsRecyclable>
    {
        public TransferAsyncEventArgsRecylePool(int maxLengh,int minLength):base(maxLengh,minLength)
        {
            base.Init();
        }

        #region Overrides of RecyclablePool<IRecyclable>

        /// <summary>
        ///     构建一个新的对象,该函数必须由继承的类实现
        /// </summary>
        /// <returns></returns>
        protected override TransferAsyncEventArgsRecyclable CreateRecyclableObject()
        {
            var temp = new TransferAsyncEventArgsRecyclable(this);

            return temp;
        }

        #endregion
    }


}
